﻿using System;
using System.ComponentModel;
using System.Windows;

using SBPweb.RIA.Shared.Contracts.Events;
using SBPweb.RIA.Shared.Contracts.Extensibility;

using SBPweb.RIA.Client.Contracts.Base;

namespace SBPweb.RIA.Client.Controls.Base
{

    public class ExtendableApplication : Application, IExtendableApplication
    {

        #region Private fields

        private ApplicationSettings settings;
        private ApplicationLocalCache localAppCache;
        private SiteLocalCache localSiteCache;

        #endregion

        #region Constructor

        public ExtendableApplication()
            : this(null)
        {
        }

        public ExtendableApplication(LocalStoreFormatterBase storageFormatter)
        {
            settings = ApplicationSettings.Load(storageFormatter);
            localAppCache = ApplicationLocalCache.Load(storageFormatter);
            localSiteCache = SiteLocalCache.Load(storageFormatter);
            settings.IgnoreDuringPersistency("InitialParameters");
            try
            {
#if !WINDOWS_PHONE
                string h = Host.Source.OriginalString.Substring(0, Host.Source.OriginalString.LastIndexOf("/") + 1);
                int i = h.LastIndexOf("/ClientBin/");
                if (i >= 0)
                {
                    h = h.Substring(0, i + 1);
                }
                HostBaseUri = new Uri(h);
                try
                {
                    PageUri = System.Windows.Browser.HtmlPage.Document.DocumentUri;
                }
                catch
                {
                }
#else
                HostBaseUri = new Uri("/", UriKind.RelativeOrAbsolute);
#endif
            }
            catch
            {
            }
            this.Exit += new EventHandler(ExtendableApplication_Exit);
        }

        private void ExtendableApplication_Exit(object sender, EventArgs e)
        {
            PersistSettings();
            PersistLocalCache();
        }

        #endregion
        
        #region Property accessors

        public ApplicationSettings Settings
        {
            get
            {
                return settings;
            }
        }

        public ApplicationLocalCache LocalApplicationCache
        {
            get
            {
                return localAppCache;
            }
        }

        public SiteLocalCache LocalSiteCache
        {
            get
            {
                return localSiteCache;
            }
        }

        public static new ExtendableApplication Current
        {
            get
            {
                return Application.Current as ExtendableApplication;
            }
        }

        public T Get<T>(string propertyName)
        {
            return settings.Get<T>(propertyName);
        }

        public void Put<T>(string propertyName, T value)
        {
            //if (RootVisual != null)
            //{
            //    RootVisual.Dispatcher.BeginInvoke( () =>
            //    {
            //        extensions.Put<T>(propertyName, value);
            //    });
            //}
            //else
            //{
                settings.Put<T>(propertyName, value);
            //}
        }

        public Uri HostBaseUri
        {
            get
            {
                return this.Get<Uri>("HostBaseUri");
            }
            private set
            {
                this.Put<Uri>("HostBaseUri", value);
            }
        }

        public Uri PageUri
        {
            get
            {
                return this.Get<Uri>("PageUri");
            }
            private set
            {
                this.Put<Uri>("PageUri", value);
            }
        }

        public IExtendable InitParams
        {
            get
            {
                return this.Get<IExtendable>("InitialParameters");
            }
            protected set
            {
                this.Put<IExtendable>("InitialParameters", value);
            }
        }

        public bool IsDesignTime
        {
            get
            {
                if (this.RootVisual == null)
                {
                    return false;
                }
                return System.ComponentModel.DesignerProperties.GetIsInDesignMode(this.RootVisual);
            }
        }

        public bool IsSettingsPersistencyEnabled
        {
            get;
            protected set;
        }

        public bool IsLocalCachePersistencyEnabled
        {
            get;
            protected set;
        }
        
#if WINDOWS_PHONE
        public object _UnknownContent
        {
            get;
            set;
        }
#endif

        #endregion

        #region Events

        public event EventHandler<EventArgs<string>> PropertyChanged
        {
            add
            {
                settings.PropertyChanged += new EventHandler<EventArgs<string>>(value);
            }
            remove
            {
                settings.PropertyChanged -= new EventHandler<EventArgs<string>>(value);
            }
        }

        #endregion

        #region Methods

        public virtual void InitializeComponent()
        {
        }

        public void PersistSettings()
        {
            if (IsSettingsPersistencyEnabled)
            {
                settings.Save();
            }
        }

        public void PersistLocalCache()
        {
            if (IsLocalCachePersistencyEnabled)
            {
                localAppCache.Save();
                localSiteCache.Save();
            }
        }

        #endregion

        #region Subclasses

        private class ExtendableDictionary : ExtendableBase
        {
        }

        #endregion

    }

}